using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace Pokemon
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Boom : DrawableGameComponent, ITappedInner
    {
        private Vector2 _position;        

        private List<Sprite> _sprite = new List<Sprite>();

        private static int _delay;

        protected TimeSpan _delayTimeSpan;//Thuoc tinh cho biet thoi gian no cua boom

        protected TimeSpan _TimeSpan;//Thuoc tinh dung de lam giam toc do thay doi khung hinh cua unit

        protected int _frameIndex;

        private int _damage;

        private int _velocity = 0;

        private bool _isTap;//Bien kiem tra da duoc user tap vao chua

        public Boom(Game game, Vector2 position)
            : base(game)
        {
            Position = position;
            Initialize();
            NormalizePosition();
            _frameIndex = 0;
        }

        public Vector2 Position
        {
            get { return _position; }
            set { _position = value; }
        }

        public List<Sprite> Sprite
        {
            get { return _sprite; }
        }

        public int FrameIndex
        {
            get { return _frameIndex; }
        }

        private void NormalizePosition()
        {
            return;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            XDocument doc = XDocument.Load(@"Content/Textures/Special/Boom/BoomDef.xml");
            Texture2D texture = null;
            Vector2 frameSize = Vector2.Zero;
            Vector2 centerPoint = Vector2.Zero;
            int numFrame = 0;
            if (doc.Document != null)
            {
                //get delay time(s)
                XName name = XName.Get("Delay");
                var definitions = doc.Document.Descendants(name);
                _delay = Int32.Parse((definitions.First()).Value);

                name = XName.Get(@"Damage");
                definitions = doc.Document.Descendants(name);
                _damage = Int32.Parse(definitions.First().Value);

                // get properties
                name = XName.Get(@"Definition");
                definitions = doc.Document.Descendants(name);

                foreach (var def in definitions)
                {
                    var xAttribute = def.Attribute(@"SheetName");
                    if (xAttribute != null)
                    {
                        texture = Game.Content.Load<Texture2D>(xAttribute.Value);

                        xAttribute = def.Attribute(@"FrameWidth");
                        if (xAttribute != null)
                        {
                            var width = float.Parse(xAttribute.Value);
                            xAttribute = def.Attribute(@"FrameHeight");
                            if (xAttribute != null)
                            {
                                var height = float.Parse(xAttribute.Value);
                                frameSize = new Vector2(width, height);
                            }
                        }

                    }

                    xAttribute = def.Attribute(@"SplitFrame");
                    numFrame = Int32.Parse(xAttribute.Value);

                    xAttribute = def.Attribute(@"XCenterPoint");

                    var xCenterPoint = Int32.Parse(xAttribute.Value);
                    xAttribute = def.Attribute(@"YCenterPoint");

                    var yCenterPoint = Int32.Parse(xAttribute.Value);

                    centerPoint = new Vector2(xCenterPoint, yCenterPoint);
                    Sprite.Add(new Sprite(texture, numFrame, frameSize, centerPoint, false));                    
                }

            }
            base.Initialize();
        }

        private Blank GetBlank()
        {
            LayerManager layer = Game.Services.GetService(typeof (LayerManager)) as LayerManager;
            List<GameComponent> list = layer.GetLayer(0);
            Grid g = null;
            foreach (var gameComponent in list)
            {
                if (gameComponent is Grid)
                    g = gameComponent as Grid;
                break;
            }
            if (g != null)
            {
                Vector2 centerPoint = Sprite[_frameIndex].CenterPoint;
                Blank blank = g.FindBlank(new Point((int) (Position.X + centerPoint.X), (int) (Position.Y + centerPoint.Y)));
                return blank;
            }
            return null;
        }

        public override void Update(GameTime gameTime)
        {
            try
            {
                _delayTimeSpan += gameTime.ElapsedGameTime;
                _TimeSpan += gameTime.ElapsedGameTime;
                if (_TimeSpan.Milliseconds < 200)
                    return;
                base.Update(gameTime);
                _TimeSpan = TimeSpan.Zero;
                Blank blank = GetBlank();
                if (blank.Pokemon == null || _frameIndex == 1)
                {
                    _velocity += 1;
                    _position.X += -_velocity;
                }
                if (_delayTimeSpan.TotalSeconds >= 3 && _frameIndex == 0)
                {
                    _frameIndex = 1;
                    Position += new Vector2(-29, -55);
                }
                Sprite[_frameIndex].Update();
                if (_frameIndex == 1)
                    if (Sprite[_frameIndex].FrameIndex == 8)
                    {
                        if (!_isTap)
                        {
                            if (blank.Pokemon != null)
                                blank.Pokemon.TakeDamage(_damage, Color.White);
                        }
                        else
                        {
                            blank.boomExploring += Explore;
                            blank.OnBoomExploring();
                            blank.boomExploring -= Explore;
                        }
                    }
                    else
                        if (Sprite[_frameIndex].FrameIndex == Sprite[_frameIndex].NFrame - 1)
                        {
                            BoomManager boomManager = Game.Services.GetService(typeof(BoomManager)) as BoomManager;
                            if (boomManager != null)
                            {
                                boomManager.Remove(this);
                            }
                        }
            }
            catch (Exception)
            {                
                throw;
            }
           
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch sp = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
            Sprite[_frameIndex].Draw(sp, Position, Color.White);
        }

        #region ITappedInner Members

        public bool CheckTapped(Point p)
        {
            Rectangle rect = new Rectangle((int)Position.X, (int)Position.Y, (int)Sprite[_frameIndex].Size.X, (int)Sprite[_frameIndex].Size.Y);
            if (!rect.Contains(p))
                return false;
            BoomManager boomManager = Game.Services.GetService(typeof (BoomManager)) as BoomManager;
            if (boomManager != null)
                boomManager.Remove(this);
            return true;
        }

        private void Explore(List<DrawableGameComponent> list)
        {
            foreach (var drawableGameComponent in list)
            {
                var zombie = drawableGameComponent as Zombie;
                if (zombie != null)
                    zombie.TakeDamage(_damage, Color.White);
            }
        }

        #endregion
    }
}
